#include "RecursoDeAlmacenamiento.h"
#include "../../tests/Persona.h"

//archivo
RecursoDeAlmacenamiento::RecursoDeAlmacenamiento(char *path, TipoAlmacenamiento tipoA, TipoEstrategia tipoE,TipoMemoria tipoM, TipoIndice tipoI , PrimaryKey *PK){
	
	/*printf("path %s\n", path);
	printf("a %d\n", tipoA);
	printf("e %d\n", tipoE);
	printf("m %d\n", tipoM);
	printf("i %d\n", tipoI);*/
	
	FILE *fpAux = fopen(path,"r");
	if(fpAux!=NULL){
	               // existe
       	  fclose(fpAux);
          this->fp= fopen(path, "rb+");	               
    }
    else{
  	               // no existe
    	this->fp= fopen(path, "wb+");
    }
	this->ptrBuff=NULL;
	this->definirAlmacenemiento(tipoA);
	//EtgRecUnAlmacenamiento * uni=
	this->recurso =(EstrategiaRecurso*)new EtgRecUnAlmacenamiento(tipoM, tipoI,/* this->indice,*/ tipoA, tipoE, this->almacenamiento, (void*)this->fp, PK);

}
//buffer
RecursoDeAlmacenamiento::RecursoDeAlmacenamiento(unsigned int tamBuffer, TipoAlmacenamiento tipoA, TipoEstrategia tipoE, TipoMemoria tipoM, TipoIndice tipoI , PrimaryKey *PK){
	this->fp= NULL;
	Buffer::getInstance()->setTamanio(tamBuffer);
	this->ptrBuff=Buffer::getInstance()->getPointer();
	//definirIndice(tipoI, PK);
	this->definirAlmacenemiento(tipoA);
	//EtgRecUnAlmacenamiento * uni=
	this->recurso =(EstrategiaRecurso*)new EtgRecUnAlmacenamiento(tipoM, tipoI,/* this->indice,*/ tipoA, tipoE, this->almacenamiento, this->ptrBuff, PK);
}
		
// ambos
RecursoDeAlmacenamiento::RecursoDeAlmacenamiento(char *path, unsigned int tamBuffer, TipoAlmacenamiento tipoA, TipoEstrategia tipoE, TipoMemoria tipoM, TipoIndice tipoI , PrimaryKey *PK){

	
	
	FILE *fpAux = fopen(path,"r");
	if(fpAux!=NULL){
          this->fp= fopen(path, "rb+");	               
       	  fclose(fpAux);
    }
    else{
    	this->fp= fopen(path, "wb+");
    }
  	Buffer::getInstance()->setTamanio(tamBuffer);
	this->ptrBuff=Buffer::getInstance()->getPointer();
	//definirIndice(tipoI, PK);
	this->definirAlmacenemiento(tipoA);
	//EtgRecEscrituraDirecta * dir=
	this->recurso= (EstrategiaRecurso*)new EtgRecEscrituraDirecta(tipoM, tipoI, tipoA, tipoE, this->almacenamiento, (void*)this->fp,PK);

}
	
void RecursoDeAlmacenamiento::definirAlmacenemiento(TipoAlmacenamiento tipo){

	this->almacenamiento = (Almacenamiento**)malloc(2*sizeof(Almacenamiento*));
	
	if (tipo==BUFFER){
		this->almacenamiento[0]= new AlmacenamientoBuffer(new Compuesto());
		this->almacenamiento[1]=NULL;
	}
	else if (tipo==ARCHIVO){
		this->almacenamiento[0]=NULL; 
		this->almacenamiento[1]= new AlmacenamientoDisco(new Compuesto());	
	}
	else{
		this->almacenamiento[0]= new AlmacenamientoBuffer(new Compuesto());
		this->almacenamiento[1]= new AlmacenamientoDisco(new Compuesto());	
	}	

}

void RecursoDeAlmacenamiento::definirIndice(TipoIndice tipoI, PrimaryKey *PK){
	switch(tipoI){
	case HASH: this->indice= new IndiceHashExtensible(PK);break;
	default: this->indice= new IndiceArbolB(PK);
	}

}

	

void RecursoDeAlmacenamiento::insertar(Dato *dato){
	try{
 	    this->recurso->insertar(dato);
    }
    catch(exception *e){
        throw e;
    }
}
		
void RecursoDeAlmacenamiento::modificar(Dato *datoAux){
    try{
    	this->recurso->modificar(datoAux);
    }
    catch(exception *e){
        throw e;
    }

}
		
void RecursoDeAlmacenamiento::eliminar(Dato *datoAux){
	try{
 	    this->recurso->eliminar(datoAux);
    }
    catch(exception *e){
        throw e;
    }
	
}
		
void RecursoDeAlmacenamiento::leer(Dato *datoAux){
	
	//((Persona*)datoAux)->print();
	try{
 	    this->recurso->	leer(datoAux);
    }
    catch(exception *e){
        throw e;
    }
	
}
	
/*	//TODO	
void RecursoDeAlmacenamiento::listar(Dato *dini, Dato *dfin){
	this->recurso->listar(dini, dfin);
}
*/
RecursoDeAlmacenamiento::~RecursoDeAlmacenamiento(){
	
	if (this->fp !=NULL) fclose(this->fp);
	delete (Buffer::getInstance());
    delete(this->indice);
/*    if(this->almacenamiento[0]!=NULL)
        delete(this->almacenamiento[0]);                                              
    if(this->almacenamiento[1]!=NULL)
        delete(this->almacenamiento[1]);                                                        
 */	free(this->almacenamiento);
}


